package org.medusa.buffer;

public class LineBuffer extends Buffer {
	
	protected byte[] buffer = null;
	protected int buffer_size;
	protected int read_offset;
	protected int write_offset;
	protected int expand_size;
	
	public LineBuffer(int capacity, int expand_size) {
		super();
		this.buffer = new byte[capacity];
		this.buffer_size = capacity;
		this.read_offset = 0;
		this.write_offset = 0;
		this.expand_size = expand_size;
	}

	// clear
	@Override
	public void Clear() {
		this.read_offset = this.write_offset = 0;
	}

	@Override
	public boolean IsFull() {
		return (this.write_offset == this.buffer_size);
	}
	
	@Override
	public boolean IsEmpty() {
		return (this.write_offset == 0);
	}
	
	// size
	@Override
	public int BufferSize() {
		return this.buffer_size;
	}
	
	public int ExpandSize() {
        return this.expand_size;
    }
	
	@Override
	public int DataSize() {
		return this.write_offset - this.read_offset;
	}

	@Override
	public int FreeSize() {
		return this.buffer_size - this.write_offset;
	}

	@Override
	public int LineDataSize() {
		return this.DataSize();
	}

	@Override
	public int LineFreeSize() {
		return this.FreeSize();
	}

	// Byte
	@Override
	public byte ReadInt8() {
		byte ret = 0;
		if(this.read_offset<this.write_offset) {
			ret = this.buffer[this.read_offset];
			this.add_read_offset(1);
		}
		
		return ret;
	}

	@Override
	public void WriteInt8(byte val) {
		if ((this.write_offset + 1) > this.buffer_size) {
			int new_buff_size = this.buffer_size + this.expand_size;
			byte[] new_databuf = new byte[new_buff_size];

			System.arraycopy(this.buffer, 0, new_databuf, 0, this.write_offset);
			this.buffer = new_databuf;
			this.buffer_size = new_buff_size;
		}

		this.buffer[this.write_offset] = val;
		this.add_write_offset(1);
	}

	// offset
	protected int add_read_offset(int offset) {
		this.read_offset += offset;
		return this.read_offset;
	}

	protected int add_write_offset(int offset) {
		this.write_offset += offset;
		return this.write_offset;
	}

	// Bytes
	public byte[] GetBytes() {
		return this.buffer;
	}

	public int GetReadOffset() {
		return this.read_offset;
	}

	public int GetWriteOffset() {
		return this.write_offset;
	}

}
